﻿/* ----------------------------------------------------------------------------
 * Copyright (c) Philip Stears 
 *
 * This source code is subject to terms and conditions of the Microsoft Public 
 * License (Ms-PL).
 * 
 * By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * To request a copy of the Microsoft Public License, send a request by email
 * to license@connectbasic.net.
 *
 * This notice must not be removed from this software.
 * ---------------------------------------------------------------------------- */

namespace ConnectBasic.Shell.Implementation
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Windows.Forms;
    using ConnectBasic.Shell.Extensibility;

    internal class DefaultShellToolWindowCollection : IToolWindowCollection
    {
        private List<IToolWindow> mWindows = new List<IToolWindow>();
        private Dictionary<string, IToolWindow> mWindowsByName = new Dictionary<string, IToolWindow>(StringComparer.OrdinalIgnoreCase);

        #region IToolWindowCollection Members

        public IToolWindow Add(string invariantName, string displayName, Type controlType)
        {
            if (invariantName == null) throw new ArgumentNullException("invariantName");
            if (displayName == null) throw new ArgumentNullException("displayName");
            if (controlType == null) throw new ArgumentNullException("controlType");

            // Make sure the type:
            // a) is a control
            // b) has a constructor which takes an IShell 
            if (!controlType.IsSubclassOf(typeof(Control))) throw new ArgumentOutOfRangeException("controlType");
            if (controlType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(IShell) }, null) == null) throw new ArgumentOutOfRangeException("controlType");

            // Create the tool window
            IToolWindow toolWindow = new DefaultToolWindow(invariantName, displayName, controlType);
            mWindowsByName.Add(invariantName, toolWindow); 
            mWindows.Add(toolWindow);            
            return toolWindow;
        }

        public IToolWindow this[int index]
        {
            get { return mWindows[index]; }
        }

        public IToolWindow this[string invariantName]
        {
            get { return mWindowsByName.ItemOrDefault(invariantName); }
        }

        public int Count
        {
            get { return mWindows.Count; }
        }

        #endregion

        #region IEnumerable<IToolWindow> Members

        IEnumerator<IToolWindow> IEnumerable<IToolWindow>.GetEnumerator()
        {
            return mWindows.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return mWindows.GetEnumerator();
        }

        #endregion

    }
}
